package com.java.reflection;

import com.java.reflection.test.Child;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodAPI {
    // Class中与Method相关的API：getMethods、getMethod、getDeclaredMethods、getDeclaredMethod
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> childCls = Class.forName("com.java.reflection.test.Child");
        Child childIns = (Child) childCls.newInstance();
        Method childPublicMethod = childCls.getMethod("childPublicFunc", String.class);
        
        // invoke：调用成员方法
        childPublicMethod.invoke(childIns, ""); // ChildPublicFunc
        
        // setAccessible：参数为true表示抑制访问检查，暴力访问私有成员方法
        Method childPrivateMethod = childCls.getDeclaredMethod("childPrivateFunc");
        childPrivateMethod.setAccessible(true);
        childPrivateMethod.invoke(childIns); // ChildPrivateFunc
        
        // getName：获取成员方法名
        System.out.println(childPublicMethod.getName()); // childPublicFunc
        
        // getParameterCount：获取成员方法形参个数
        System.out.println(childPublicMethod.getParameterCount()); // 1
        
        // getParameterTypes：Class形式获取成员方法的所有形参类型
        ReflectionUtil.println(childPublicMethod.getParameterTypes()); // String
        
        // getGenericParameterTypes：Type形式获取成员方法的所有形参类型
        ReflectionUtil.println(childPublicMethod.getGenericParameterTypes()); // java.lang.String
        
        // getReturnType：Class形式获取成员方法返回值类型
        System.out.println(childPublicMethod.getReturnType()); // void
        
        // getGenericReturnType：Type形式获取成员方法返回值类型
        System.out.println(childPublicMethod.getGenericReturnType()); // void
        
        // toGenericString：获取成员方法的详细信息
        System.out.println(childPublicMethod.toGenericString()); // public void com.java.reflection.test.Child.childPublicFunc(java.lang.String)
        
        // isVarArgs：判断成员方法是否携带可变参数
        System.out.println(childPublicMethod.isVarArgs()); // false
    }
}
